
package com.scalar.chiptrack.users.actions;

import java.util.ArrayList;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import org.apache.poi.ss.usermodel.Workbook;

import com.scalar.ScalarException;
import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.operations.reports.DataDumpReportsHelper;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.commons.Constants;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.jobs.Job;
import com.scalar.chiptrack.jobs.dao.JobDAO;
import com.scalar.chiptrack.users.Functionality;
import com.scalar.chiptrack.users.User;
import com.scalar.chiptrack.users.dao.UserDAO;
import com.scalar.chiptrack.users.forms.SystemJobSetupForm;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.utils.ExcelUtils;
import com.scalar.chiptrack.utils.DateUtil;

public final class SystemJobSetupAction extends ChipTrackAction
 {
    // Stores the path of the JobHandler Class.
    private static final String HANDLER_PATH = "com.scalar.chiptrack.jobs.JobHandler";

    public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response ) throws Exception
    {
		HashMap<String,String> errors 	= new HashMap<String,String>();
        HashMap<String,String> info 	= new HashMap<String,String>();

        request.setAttribute( SessionKeys.MESSAGES, errors );
        request.setAttribute( SessionKeys.INFO_MESSAGES, info );

        String action 	= request.getParameter( "action" );
        boolean success	= false;
        boolean handlerExists 	= false;
        String jobNameToSend 	= null; // Stores the Job Name to be send if any error occurs.
        HttpSession session 	= request.getSession();
        
        User user = ( User ) session.getAttribute ( SessionKeys.USER_KEY );
		
        SystemJobSetupForm subform = (SystemJobSetupForm) form;
		
        if( user != null )
        {
            if ( user.isActionAllowed ( Functionality.SYSTEM_JOB_SETUP, User.USER_ACTION_MODIFY ) )
            {
                request.setAttribute ( "showMessage", "FALSE" );
            }
            else
            {
                request.setAttribute ( "showMessage", "TRUE" );
            }
        }
        if( "save".equals( action ) )
        {
            DBTransaction dbTransaction = null;
            try
            {
                dbTransaction = DBTransaction.getInstance();
				dbTransaction.begin();

                if( isTokenValid( request ) )
                {
                    resetToken( request );
                }
                else
                {
                    throw new IllegalAccessError();
                }
                
                String[] jobId = request.getParameterValues("id");
                String[] jobName = request.getParameterValues("jobName");
                String[] jobHandler = request.getParameterValues("handler");
                String[] startTime = request.getParameterValues("startTime");

                for( int i = 0; i < jobId.length; i++ )
                {
                	if( jobId[i].equals("") )
                	{
                		jobId[i] = "-1";
                	} 
                   
                	// If the job Name field does not contain any value then do not insert
                   	if( !jobName[i].trim().equals( "" ) )
                   	{
                   		jobNameToSend 	= jobName[i];
                   		Job job 		= new Job(Integer.parseInt(jobId[i]),jobName[i],jobHandler[i].trim(), StringUtils.format(startTime[i]));
                   		job.setIsSystem(true);

                   		// -- This Process Checks if the Handler class exists and also checks if the handler class extends JobHandler class.
                        Class subclass 		= Class.forName( jobHandler[i].trim() );
                        Class superclass 	= subclass.getSuperclass();
						handlerExists 		= false;

						while( superclass != null )
                        {
							String className = superclass.getName();
                            if( className.equals( HANDLER_PATH ) )
                            {
                            	handlerExists = true;
                                break;
                            }
                            subclass 	= superclass;
                            superclass 	= subclass.getSuperclass();
    					}
                        
						if( handlerExists == true )
						{
							if( jobId[i].equals( "-1" ) || ( jobId[i] == "-1" ) )
							{
								JobDAO.insertJob(dbTransaction,job);
							}
                            else
                            {
                            	JobDAO.updateJob(dbTransaction,job);
                            }
						}
                        else
                        {
                        	throw new ScalarException();
                        }
                   	}
                }
                success = true;
                info.put ( "System Jobs information has been saved successfully", null );
                request.setAttribute( SessionKeys.INFO_MESSAGES, info );
			}
            catch (IllegalAccessError iae)
			{
                success = false;
                errors.put ( "Please Refresh the page using the System Job Setup Link to the Left", "" );
                request.setAttribute(SessionKeys.ERROR_MESSAGES, errors);
			}
            catch (ScalarException se)
			{
                success = false;
                errors.put ( "Handler is not a Valid class for Job &quot;"+jobNameToSend+"&quot;", "Could not save System Job Information" );
                request.setAttribute(SessionKeys.ERROR_MESSAGES, errors);
			}
            catch ( ClassNotFoundException cnfe )
			{
                success = false;
                errors.put ( "Handler class Does not Exists for Job &quot;"+jobNameToSend+"&quot;" , "Could not save System Job Information" );
                request.setAttribute( SessionKeys.ERROR_MESSAGES, errors );
			}
			catch ( Throwable t )
			{
                success = false;
                t.printStackTrace();
                errors.put ( "Internal Server Error", "Could not save System Job Information");
                request.setAttribute(SessionKeys.ERROR_MESSAGES, errors);
			}
			finally
            {
				if( dbTransaction != null )
				{
					if( success == true ) 
					{
						dbTransaction.commit();
	                    info.put( "System Job Setup Saved Successfully", null );
					}
					else
	                {
						dbTransaction.rollback();
					}
				}
			}
		}
        else if( "changestatus".equalsIgnoreCase( action ) )
        {
            String jobId 	= null;
            String jobName 	= null;
            String status 	= request.getParameter("selectedstatus");
            String removedValue 	= "";
            
            if( status.equalsIgnoreCase( "true" ) )
            {
               removedValue = "1";
               status 		= "Activated";
            }
            else if( status.equalsIgnoreCase( "false" ) )
            {
               removedValue = "0";
               status 		= "Disabled";
            }
            
            try
            {
            	jobId 	= request.getParameter( "delid" );
                jobName = request.getParameter( "delname" );
                JobDAO.removeJobByIdInJobs( jobId, removedValue );
                success = true;
            }
            catch( Throwable t )
			{
                t.printStackTrace();
                errors.put ( "Internal Server Error", "Could not Delete Job Information" );
			}
			finally
            {
				if (success == true)
                { 
					info.put( "Job " + jobName + " has been " + status, null );
			    }
			}
        }
        //This is will be executed when you click on the Schedule link in "System Job Setup" Screen.
        else if( "scheduleJob".equalsIgnoreCase( action ) )
        {
            int jobId 		= 0;
            String jobName 	= null;
            Job job 		= null;

            //getting the jobID and jobName for which Scheduling to be done.
            jobId 	= Integer.parseInt( request.getParameter( "delid" ) );
            jobName = request.getParameter( "delname" );

            //Job ID is valid, loading the Job and forwarding to System "Job Schedule" Screen.
            if ( jobId > 0 )
            {
                job = JobDAO.loadJobScheduleInfoById( jobId );
                subform.setJob( job );
                return( mapping.findForward( "scheduleJob" ) );
            }
            else
            {
               errors.put( "System Job Schedule","Unable to Schedule Job " + jobName );
            }
        }
        else if ( "showUserMailIDs".equalsIgnoreCase ( action ) )
        {
            ArrayList usersMailIDs = new ArrayList ();
            usersMailIDs = UserDAO.loadAllUsersWithNameAndEmail();
            request.setAttribute ( "usersMailIDs", usersMailIDs );
            return ( mapping.findForward ( "showUserMailIDs" ) );
       	}
        else if ( "showJobEmailUsers".equalsIgnoreCase ( action ) )
        {
            String[] emailUserIds = JobDAO.getJobEmailUserIds ( null, subform.getJob().getId() );
            subform.getJob().setEmailUserId( emailUserIds);
            ArrayList users = UserDAO.loadAllUsers( false, Constants.USER_TYPE_ALL );
            request.setAttribute ( "users", users );
            return ( mapping.findForward ( "showJobEmailUsers" ) );
       	}
        else if ( "saveEmailUserIds".equalsIgnoreCase ( action ) )
        {
            try
            {
                JobDAO.saveJobEmailUserIds( null, subform.getJob().getId(), subform.getJob().getEmailUserId() );
                info.put( "Successfully saved Job Email Users", null );
            }
            catch ( ScalarException ex )
            {
                errors.put ( "Could not save Job Email Users", null );
            }
            String[] emailUserIds = JobDAO.getJobEmailUserIds ( null, subform.getJob().getId() );
            subform.getJob().setEmailUserId( emailUserIds);
            ArrayList users = UserDAO.loadAllUsers( false, Constants.USER_TYPE_ALL );
            request.setAttribute ( "users", users );
            return ( mapping.findForward ( "showJobEmailUsers" ) );
       	}
        else if ("exporttoexcel".equalsIgnoreCase(action))
        {

            ArrayList jobStatusList = new ArrayList();

            Workbook workbook = null;
            String fileName = null;

            try
            {
                jobStatusList = JobDAO.loadAllJobSetupInfoExcel ( null );
                workbook =  DataDumpReportsHelper.getWorkbook( jobStatusList, "Job SetUp Report",null,null,null );
                fileName = "jobsetUpReport_"+ DateUtil.getTimeStamp();
            }

            catch ( Exception e )
            {
                errors.put ( "Could not Generate Excel File", null );
                e.printStackTrace();
            }
            ExcelUtils.generateExcelReport( workbook, fileName, response);
            return null;
        }
       else if( "saveJobSchedule".equalsIgnoreCase( action ) )
       	{
       	    Job job = subform.getJob ();
                       
            if( job.getId() > 0 )
            {
                try
				{
                    JobDAO.udpateJobScheduleInfo(job);
                    info.put( "System Job Schedule Information for &quot;"+ job.getJobName() +"&quot; has been saved successfully", null );
                }
                catch( Exception sqle )
                {
                    sqle.printStackTrace();
                    throw new ScalarException( "Could not save Job Scheduling Info into database", sqle );
                }
            }
       	}
        saveToken( request );
        request.setAttribute( "jobsList", JobDAO.loadSystemJobs() );

		// Report any errors we have discovered back to the original form
        /*if( !errors.isEmpty() )
        {
        	request.setAttribute( SessionKeys.MESSAGES, errors );
        }
        if( !info.isEmpty() )
        {
        	request.setAttribute( SessionKeys.INFO_MESSAGES, info );
        }*/
        
	 	return ( mapping.findForward( "success" ) );
    }
}
